package com.zc.campus_shops.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.zc.campus_shops.dao.ProductDao;
import com.zc.campus_shops.dao.ProductImgDao;
import com.zc.campus_shops.dto.ImageHolder;
import com.zc.campus_shops.dto.ProductExecution;
import com.zc.campus_shops.entity.Product;
import com.zc.campus_shops.entity.ProductImg;
import com.zc.campus_shops.enums.ProductStateEnum;
import com.zc.campus_shops.exception.ProductOperationException;
import com.zc.campus_shops.service.ProductService;
import com.zc.campus_shops.util.ImageUtil;
import com.zc.campus_shops.util.PageCalculator;
import com.zc.campus_shops.util.PathUtil;

@Service
public class ProductServiceImpl implements ProductService {

	@Autowired
	private ProductDao productDao;

	@Autowired
	private ProductImgDao productImgDao;

	@Override
	@Transactional
	/***
	 * 1.处理缩略图，获取相对路径并赋值给product 2.往表tb_product写入商品信息，获取productId
	 * 3.结合productId批量处理商品详情图 4.将详情图列表批量插入表tb_product_img中
	 */
	public ProductExecution addProduct(Product product, ImageHolder thumbnail, List<ImageHolder> productImgHolderList)
			throws ProductOperationException {
		// 空值判断
		if (product != null && product.getShop() != null && product.getShop().getShopId() != null) {
			// 给商品设置上默认属性
			product.setCreateTime(new Date());
			product.setLastEditTime(new Date());
			// 默认为上架的状态
			product.setEnableStatus(1);
			// 若缩略图不为空则添加
			if (thumbnail != null) {
				addThumbnail(product, thumbnail);
			}
			try {
				// 创建商品信息
				int effectedNum = productDao.insertProduct(product);
				if (effectedNum <= 0) {
					throw new ProductOperationException("添加商品失败");
				}
			} catch (Exception e) {
				throw new ProductOperationException("添加商品失败" + e.toString());
			}
			// 如果商品详情图不为空的话 就添加
			if (productImgHolderList != null && productImgHolderList.size() > 0) {
				addProductImgList(product, productImgHolderList);
			}
			return new ProductExecution(ProductStateEnum.SUCCESS, product);

		} else {
			// 传参为空则返回空值错误信息
			return new ProductExecution(ProductStateEnum.EMPTY_LIST);
		}

	}

	/**
	 * 批量添加图片
	 * 
	 * @param product
	 * @param productImgHolderList
	 */
	private void addProductImgList(Product product, List<ImageHolder> productImgHolderList) {
		// 获取图片的存储路径,这直接存到相应店铺的文件夹下
		String dest = PathUtil.getShopImagePath(product.getShop().getShopId());
		List<ProductImg> productImgList = new ArrayList<ProductImg>();
		// 遍历图片 并处理 ，添加到productImg的实体类 （数据库）
		for (ImageHolder productImgHolder : productImgHolderList) {
			String imgAddr = ImageUtil.generateNormalImg(productImgHolder, dest);
			ProductImg productImg = new ProductImg();
			productImg.setImgAddr(imgAddr);
			productImg.setProductId(product.getProductId());
			productImg.setCreateTime(new Date());
			productImgList.add(productImg);
		}
		// 如果前台传过来图片 确实是有图片要添加 就执行批量的添加操作
		if (productImgList.size() > 0) {
			try {
				// 插入数据库中
				int effectedNum = productImgDao.batchInsertProductImg(productImgList);
				if (effectedNum <= 0) {
					throw new ProductOperationException("创建商品详情图失败");
				}
			} catch (Exception e) {
				throw new ProductOperationException("创建商品详情图失败" + e.toString());
			}
		}
	}

	/**
	 * 添加缩略图
	 * 
	 * @param product
	 * @param thumbnail
	 */
	private void addThumbnail(Product product, ImageHolder thumbnail) {
		// 获取根路径
		String dest = PathUtil.getShopImagePath(product.getShop().getShopId());
		// 创建图片，并获取图片的相对路线
		String thumbnailAddr = ImageUtil.generateThumbnail(thumbnail, dest);
		product.setImgAddr(thumbnailAddr);

	}

	@Override
	public Product getProductById(long productId) {
		return productDao.queryProductById(productId);
	}

	@Override
	@Transactional
	public ProductExecution modifyProduct(Product product, ImageHolder thumbnail, List<ImageHolder> productImgList)
			throws ProductOperationException {
		// 空值判断
		if (product != null && product.getShop() != null && product.getShop().getShopId() != null) {
			// 设置默认属性
			product.setLastEditTime(new Date());
			// 若商品缩略图不为空 且原有缩略图不为空则删除原有缩略图并添加
			if (thumbnail != null) {
				// 先获取原有信息 因为原有信息有原有图片地址
				Product tempProduct = productDao.queryProductById(product.getProductId());
				if (tempProduct.getImgAddr() != null) {

					ImageUtil.deleteFileOrPath(tempProduct.getImgAddr());
				}
				addThumbnail(product, thumbnail);
			}

			// 如果有新存入的商品详情图，则将原来的删除，并添加新的图片
			if (productImgList != null && productImgList.size() > 0) {
				deleteProductImgList(product.getProductId());
				addProductImgList(product, productImgList);
			}
			try{
				//更新商品信息
				int effectedNum = productDao.updateProduct(product);
				if(effectedNum <= 0){
					throw new ProductOperationException("更新商品失败");
				}
				return new ProductExecution(ProductStateEnum.SUCCESS,product);
				
			}catch(Exception e){
				throw new ProductOperationException("更新商品失败" + e.toString());
			}
		}else{
			return new ProductExecution(ProductStateEnum.EMPTY_LIST);
		}
		
	}

	/**
	 * 删除某个商品下的所有详情图
	 * 
	 * @param productId
	 */
	private void deleteProductImgList(long productId) {

		// 根据productId获取原来的图片
		List<ProductImg> productImgList = productImgDao.queryProductImgList(productId);
		// 删掉原来的图片
		for (ProductImg productImg : productImgList) {
			ImageUtil.deleteFileOrPath(productImg.getImgAddr());
		}
		// 删除数据库的图片信息
		productImgDao.deleteProductImgByProductId(productId);

	}

	/**
	 * 获取商品的商品列表分页查询
	 */
	@Override
	public ProductExecution getProductList(Product productCondition, int pageIndex, int pageSize) {
		//页码转换为数据的行码，并调用dao层取回制定页码的商品列表
		int rowIndex = PageCalculator.calculateRowIndex(pageIndex, pageSize);
		List<Product> productList = productDao.queryProductList(productCondition, rowIndex, pageSize);
		//基于同样的查询条件返回查询条件下的商品总数
		int count = productDao.queryProductCount(productCondition);
		ProductExecution pe = new ProductExecution();
		pe.setProductList(productList);
		pe.setCount(count);
		
		return pe;
	}

}
